package gameComponents;
import gamePieces.Queen;

import java.awt.Point;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;


/**
 * Game engine for 8 Queens game. Utilized by Controller to carry out
 * the playing of the game.
 * 
 * @author Jordan Beland, edited by Vivian Andreeva
 *
 */
public class QueenGame extends SuperGame{
	
	//Creates a new chess board instance
	private Board board;
	//Creates a new ArrayList of Queens to place on the chess board
	private ArrayList<Queen> queens;
	private Scanner in;
	// Remove option if the user wishes to remove a Queen from the chess board
	private static final int REMOVE = 8;
	private Player player;
	
	/**
	 * Constructor for class Game.
	 * 
	 * @author Jordan Beland
	 */
	public QueenGame(){
		this.board = new Board();
		this.queens = new ArrayList<Queen>();
		this.in = new Scanner(System.in);
		this.player = new Player(1);
	}
	
	/**
	 * Method uses input coordinates from user and places queen
	 * at coordinates if it's a legal move. Otherwise notifies
	 * user it is not a legal move, and does nothing.
	 * 
	 * @author Jordan Beland
	 * @param x
	 * @param y
	 */
	public void placeQueen(int x, int y){
		//check if coordinates are out of bounds
		if(x >= Board.SIZE || x < 0 || y >= Board.SIZE || y < 0){
			System.out.println("Out of Bounds, Not a legal move!");
		}else if(legalMove(x,y)){ // check if coordinates are a legal move
			queens.add(new Queen(x,y, player)); // if so, place the queen
			board.placePiece(x, y, "Q", player); // let the board know a queen is there
		}else{
			System.out.println("Not a legal move!");
		}
	}
	
	
	/**
	 * Checks if there are 8 queens on the board, if so,
	 * Game is over and user wins.
	 * 
	 * @author Jordan Beland
	 * @return True if user has won
	 */
	public boolean hasWon(){
		return queens.size() >= 8;
	}
	
	/**
	 * Checks if user has entered a no-win scenario.
	 * 
	 * @author Jordan Beland
	 * @return True if user has entered a no-win scenario
	 */
	public boolean noWin(){
		//if there is no queens on the table, winning is still possible
		if(queens.size() == 0) return false;
		//create an arraylist of all coordinates of board
		ArrayList<Point> tempBoard= new ArrayList<Point>();
		for(int i = 0; i < Board.SIZE; i++){
			for(int j = 0; j < Board.SIZE; j++){
				tempBoard.add(new Point(i,j));
			}
		}
		int x;
		int y;
		ArrayList<Point> toRemove = new ArrayList<Point>();
		//for each queen, remove all of its possible moves and 
		//position from the board's coordinates
		for(Queen q : queens){
			//first, remove the current position of the queen
			x = q.getX();
			y = q.getY();
			//get the points to remove
			for(Point p : tempBoard){
				if(p.x == x && p.y == y)toRemove.add(p);
			}
			//remove them
			for(Point p: toRemove){
				tempBoard.remove(p);
			}
			//clear list
			toRemove.clear();
			//find the coordinates to remove all of her possible moves
			ArrayList<Point> moves = q.getMoves();
			for(Point p : moves){
				for(Point r : tempBoard){
					if(r.x == p.x && r.y == p.y)toRemove.add(r);
				}
			}
			//remove them
			for(Point p: toRemove){
				tempBoard.remove(p);
			}
			toRemove.clear(); //clear toRemove to start over
		}
		if(tempBoard.size() == 0)return true;
		return false;	
	}
	
	/**
	 * Checks if the attempted move is in accordance
	 * with the rules of the game.
	 * 
	 * @author Jordan Beland
	 * @param x coordinate of new location
	 * @param y coordinate of new location
	 * @return True if it is a legal move
	 */
	public boolean legalMove(int x, int y){
		// if there are no queens on the table
		// the move must be legal
		if(queens.size() == 0) return true;
		// Get each queen currently on the table
		for(Queen q : queens){
			// if there is a queen already there, can't place another
			if(x == q.getX() && y == q.getY()) return false;
			//check if the coordinates are in the path of a queen's moves
			ArrayList<Point> moves = q.getMoves();
			for(Point p : moves){
				if(x == p.x && y == p.y) return false;
			}
		}
		return true;
	}
	
	/**
	 * Runs through a Game Scenario with the user.
	 * 
	 * @author Jordan Beland, edited by Vivian Andreeva
	 * @throws IOException 
	 * @throws IOException 
	 */
	public void play() throws IOException{
		String position;
		// As long as the user hasn't won or entered
		// a no-win scenario, keep going
		while(!(hasWon()) && (!(noWin()))){
			System.out.println("-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-");
			System.out.println("      Welcome to the 8 Queens Game");
			System.out.println("-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-");
			board.print(); // display board
			System.out.println("\n\n Enter a position to place a Queen");
			position = in.nextLine();
			int x = Board.convertX(position);	
			int y = Board.convertY(position);
			placeQueen(x,y); //place a queen at that location, if possible
			
		}
		if(queens.size()==8){ //did the user win?
			board.print(); //show them they did
			System.out.println("Congratulations, you won!");
		}else{
			board.print(); //show them they lost
			System.out.println("no more moves, you lose!");
		}
	}
}

